﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Autofac;
using Autofac.Extensions.DependencyInjection;
using IRepository;
using IServices;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.Swagger;

namespace AppCore
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            //当前路径
            var basePath = AppContext.BaseDirectory; //Microsoft.DotNet.PlatformAbstractions.ApplicationEnvironment.ApplicationBasePath;
            var ApiName = "AppCore";
            #region SwaggerUI
            services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new Swashbuckle.AspNetCore.Swagger.Info
                {
                    Version = "v0.1.0",
                    Title = "IoC_DI",
                    Description = "框架说明文档",
                    TermsOfService = "None",
                    Contact = new Swashbuckle.AspNetCore.Swagger.Contact { Name = "AppCore", Email = "AppCore@xxx.com", Url = "" }
                });

                //添加 注释
                var xmlPath = Path.Combine(basePath, $"{ApiName}.xml");

                //第二个参数默认是false，这个是controller注释，要写成true，不然显示不出来
                c.IncludeXmlComments(xmlPath,true);
            });
            #endregion
            #region autofac
            //实例化容器
            var builder = new ContainerBuilder();

            //注册要通过反射创建的组件(注释：需要手动引用实体层)
            //builder.RegisterType<SysSampleServices>().As<ISysSampleServices>();
            //builder.RegisterType<SysSampleRepository>().As<ISysSampleRepository>();

            //程序集注入 —— 实现层级解耦
            //通过反射将Services和Repository两个程序集的全部方法注入，要记得!!!这个注入的是实现类层，不是接口层 IServices
            
            try
            {
                //1、工程只依赖抽象，把两个实现层删掉，引用IRepository IServices这两个接口层
                //2、将 Repository 层和 Service 层项目生成地址改成相对路径，这样大家就不用手动拷贝这两个 dll 了
                //3、使用 LoadFile 加载服务层的程序集
                var repositoryDLLFile = Path.Combine(basePath+"\\netstandard2.0","Repository.dll");
                var assemblysRepository = Assembly.LoadFile(repositoryDLLFile);
                builder.RegisterAssemblyTypes(assemblysRepository).AsImplementedInterfaces();

                var servicesDLLFile = Path.Combine(basePath+"\\netstandard2.0","Services.dll");
                var assemblysServices = Assembly.LoadFile(servicesDLLFile);
                builder.RegisterAssemblyTypes(assemblysServices).AsImplementedInterfaces();

            }
            catch (System.Exception)
            {
                
                throw new Exception("请检查bin文件夹是否存在Repository.dll和service.dll");
            }
            //将Services填充到Autofac容器生成其中
            builder.Populate(services);

            //使用已进行的组件登记创新容器
            var ApplicationContainer = builder.Build();
            #endregion
            return new AutofacServiceProvider(ApplicationContainer);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                #region Swagger
                app.UseSwagger();
                app.UseSwaggerUI(c =>
                {
                    c.SwaggerEndpoint("/swagger/v1/swagger.json", "ApiHelp V1");
                    //路径配置为空，表示直接在根域名（localhost：5000）访问该文件
                    //注意localhost：5000/swagger是访问不到的，去launchSettings.json把lanuchUrl去掉
                    c.RoutePrefix = "";
                });
                #endregion
            }

            app.UseMvc();
        }
    }
}
